
import * as fse from 'fs-extra';
import { ILoggable } from '../utils/Log';

/**
 * writer interface
 */
export interface IWriter {
    /**
     * get type of writer
     */
    getType(): string;

    /**
     * write to file
     * @param file filepath
     * @param data data
     * @param encode encode, default is utf-8
     */
    writeToFile(filepath: string, data: any, encode: BufferEncoding): Promise<void>;
}

/**
 * base writer
 */
export class BaseWriter implements ILoggable, IWriter {
    public readonly DOMAIN: string;
    public readonly TAG: string;
    protected type: string;

    /**
     * get type
     * @returns type
     */
    public getType(): string {
        return this.type;
    }

    /**
     * write to file
     * @param file filepath
     * @param data data
     * @param encoding encoding, default is utf-8
     */
    public async writeToFile(filepath: string, data: any,  encoding: BufferEncoding): Promise<void> {
        const buf = Buffer.isBuffer(data) ? data : Buffer.from(data, encoding);
        fse.outputFileSync(filepath, buf);
    }
}

/**
 * text writer
 */
export class TextWriter extends BaseWriter {
    public readonly DOMAIN: string;
    public readonly TAG: string;
    protected type: string;
    protected static _instance: IWriter;

    public static instance(): IWriter {
    if (this._instance == null) {
        this._instance = new TextWriter();
    }
    return this._instance;
}

    constructor() {
        super();
        this.DOMAIN = 'meminsight';
        this.TAG = TextWriter.name;
        this.type = TextWriter.name;
    }

    public async writeToFile(filepath: string, data: any,  encoding: BufferEncoding): Promise<void> {
        super.writeToFile(filepath, data, encoding);
    }
}

/**
 * json writer
 */
export class JsonWriter extends BaseWriter {    
    public readonly DOMAIN: string;
    public readonly TAG: string;
    protected type: string;
    protected static _instance: IWriter;

    public static instance(): IWriter {
        if (this._instance == null) {
            this._instance = new JsonWriter();
        }
        return this._instance;
    }

    constructor() {
        super();
        this.DOMAIN = 'meminsight';
        this.TAG = JsonWriter.name;
        this.type = JsonWriter.name;
    }

    public async writeToFile(filepath: string, data: any, encoding: BufferEncoding): Promise<void> {
        fse.outputJSONSync(filepath, data, { encoding: encoding, spaces: 4 });
    }
}

/**
 * html writer
 */
export class HtmlWriter extends BaseWriter {
    public readonly DOMAIN: string;
    public readonly TAG: string;
    protected type: string;
    protected static _instance: IWriter;

    public static instance(): IWriter {
        if (this._instance == null) {
            this._instance = new HtmlWriter();
        }
        return this._instance;
    }

    constructor() {
        super();
        this.DOMAIN = 'meminsight';
        this.TAG = HtmlWriter.name;
        this.type = HtmlWriter.name;
    }

    public async writeToFile(filepath: string, data: any,  encoding: BufferEncoding): Promise<void> {
        super.writeToFile(filepath, data, encoding);
    }

    /**
     * 从template读取数据并将data插入模板数据中
     * @param template 模板路径
     * @param data 待插入数据
     * @param delimiter 分隔符
     * @return 插入data后的模板数据
     */
    public getDataByTemplate(template: string, data: string, delimiter: string): string {
        const templateStrs = fse.readFileSync(template, 'utf-8').split(delimiter);
        if (templateStrs.length !== 2) {
            return '';
        }
        return templateStrs[0] + delimiter + data + templateStrs[1];
    }
}